package com.niiwoo.civet.trade.service.dubbo.loan;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.trade.dto.request.loan.*;
import com.niiwoo.civet.trade.dto.response.loan.LoanConfigResDTO;
import com.niiwoo.civet.trade.dto.response.loan.LoanSubmitCommResDTO;
import com.niiwoo.civet.trade.enums.LoanLimitMessageEnum;
import com.niiwoo.civet.trade.enums.LoanSubmitTypeEnum;
import com.niiwoo.civet.trade.service.loan.LoanSubmitDubboService;
import com.niiwoo.civet.trade.service.local.loan.submit.AbstractLoanSubmitService;
import com.niiwoo.civet.trade.service.local.loan.submit.LoanSubmitServiceFactory;
import com.niiwoo.tripod.provider.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.function.BiConsumer;

/**
 * @Author: wuke
 * @Description:
 * @Date: Created in 15:36 2018/4/14
 */
@Slf4j
@Service(version = "1.0.0", validation = "true")
public class LoanSubmitDubboServiceImpl implements LoanSubmitDubboService {
    @Autowired
    private LoanSubmitServiceFactory loanSubmitServiceFactory;

    @Override
    public LoanConfigResDTO loanConfig(LoanConfigReqDTO reqDTO) {
        log.info("loanConfig.reqDTO={}", JSON.toJSONString(reqDTO));

        AbstractLoanSubmitService loanSubmitService = this.getLoanSubmitService(reqDTO.getLoanSubmitTypeEnum());

        log.info("loanConfig.loanSubmitService={}", loanSubmitService);

        LoanConfigResDTO loanConfigResDTO = loanSubmitService.getConfig(reqDTO.getUserId(),LoanConfigResDTO.class);

        log.info("loanConfig.loanConfigResDTO={}", JSON.toJSONString(loanConfigResDTO));
        return loanConfigResDTO;
    }

    @Override
    public LoanSubmitCommResDTO loanCheck(LoanSubmitCommReqDTO reqDTO) {
        log.info("loanCheck.reqDTO={}",JSON.toJSONString(reqDTO));

        AbstractLoanSubmitService loanSubmitService = this.getLoanSubmitService(reqDTO.getLoanSubmitTypeEnum());

        log.info("loanCheck.loanSubmitService={}", loanSubmitService);

        LoanSubmitCommResDTO resDTO = postConsumer(reqDTO, (req,res)->{
            LoanSubmitReqDTO r = new LoanSubmitReqDTO();
            BeanUtils.copyProperties(req,r);
            loanSubmitService.intoCheck(r,res);
        });

        log.info("loanCheck.resDTO={}",JSON.toJSONString(resDTO));
        return resDTO;
    }

    @Override
    public LoanSubmitCommResDTO loanSubmit(LoanSubmitReqDTO reqDTO) {
        log.info("loanSubmit.reqDTO={}", JSON.toJSONString(reqDTO));

        AbstractLoanSubmitService loanSubmitService = this.getLoanSubmitService(reqDTO.getLoanSubmitTypeEnum());

        log.info("loanSubmit.loanSubmitService={}", loanSubmitService);

        LoanSubmitCommResDTO resDTO = postConsumer(reqDTO, (req, res) -> {
            loanSubmitService.submit(req, res);
        });

        log.info("loanSubmit.resDTO={}", JSON.toJSONString(resDTO));
        return resDTO;
    }

    @Override
    public LoanSubmitCommResDTO loanBackSubmit(LoanBackSubmitReqDTO reqDTO) {
        log.info("loanBackSubmit.reqDTO={}",JSON.toJSONString(reqDTO));

        AbstractLoanSubmitService loanSubmitService = this.getLoanSubmitService(reqDTO.getLoanSubmitTypeEnum());

        log.info("loanBackSubmit.loanSubmitService={}", loanSubmitService);

        LoanSubmitCommResDTO resDTO = postConsumer(reqDTO, (req,res)->{
            loanSubmitService.backSubmit(req,res);
        });

        log.info("loanBackSubmit.resDTO={}",JSON.toJSONString(resDTO));
        return resDTO;
    }

    /**
     * 审核通过确认后提交借款（用户没有修改金额，提交后直接上标）
     * @param reqDTO
     * @return
     */
    @Override
    public LoanSubmitCommResDTO loanAuditConfirm(LoanAuditConfirmReqDTO reqDTO) {
        log.info("loanAuditConfirm.reqDTO={}",JSON.toJSONString(reqDTO));

        AbstractLoanSubmitService loanSubmitService = this.getLoanSubmitService(reqDTO.getLoanSubmitTypeEnum());

        log.info("loanAuditConfirm.loanSubmitService={}", loanSubmitService);

        LoanSubmitCommResDTO resDTO = postConsumer(reqDTO, (req,res)->{

            LoanAuditConfirmDTO dto = new LoanAuditConfirmDTO();
            BeanUtils.copyProperties(req, dto);
            loanSubmitService.auditConfirm(dto,res);
        });

        log.info("loanAuditConfirm.resDTO={}",JSON.toJSONString(resDTO));
        return resDTO;
    }

    /**
     * 重新确认提交检查(提额认证后确认提交借款使用，用户修改了金额：原标的流标+新生成一个标的)
     * @param reqDTO
     * @return
     */
    @Override
    public LoanSubmitCommResDTO loanReConfirmSubmit(LoanReConfirmSubmitReqDTO reqDTO) {
        log.info("loanReConfirmSubmit.reqDTO={}", JSON.toJSONString(reqDTO));

        AbstractLoanSubmitService loanSubmitService = this.getLoanSubmitService(reqDTO.getLoanSubmitTypeEnum());

        log.info("loanReConfirmSubmit.loanSubmitService={}", loanSubmitService);

        LoanSubmitCommResDTO resDTO = postConsumer(reqDTO, (req, res) -> {
            LoanReConfirmSubmitDTO dto = new LoanReConfirmSubmitDTO();
            BeanUtils.copyProperties(req, dto);
            loanSubmitService.reConfirmSubmit(dto, res);
        });

        log.info("loanReConfirmSubmit.resDTO={}", JSON.toJSONString(resDTO));
        return resDTO;
    }

    public <T> LoanSubmitCommResDTO postConsumer(T t, BiConsumer<T,LoanSubmitCommResDTO> biConsumer){
        LoanSubmitCommResDTO resDTO = new LoanSubmitCommResDTO();
        resDTO.setStatus(LoanLimitMessageEnum.LIMIT_10099.getLimitCode());

        try {
            biConsumer.accept(t,resDTO);
            resDTO.setStatus(LoanLimitMessageEnum.LIMIT_10000.getLimitCode());
        } catch (BizException bizException) {
            log.error("postConsumer",bizException);
            if(!"TRD10006".equals(bizException.getErrorCode())){
                throw bizException;
            }
        }

        return resDTO;
    }

    public AbstractLoanSubmitService getLoanSubmitService(LoanSubmitTypeEnum loanSubmitTypeEnum){
        return loanSubmitServiceFactory.getLoanSubmitService(loanSubmitTypeEnum);
    }
}
